#!/usr/bin/env python3
"""
环境检测脚本 - 中国大陆网络环境优化

检测开发环境是否符合要求，包括网络连通性、依赖包、服务可用性等。
针对中国大陆网络环境提供优化建议。
"""

import sys
import os
import time
import subprocess
import socket
from typing import Dict, List, Tuple
import importlib.util

# 添加项目路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

def check_network_connectivity() -> Dict[str, bool]:
    """检测网络连通性"""
    print("🌐 检测网络连通性...")
    
    sites = {
        'GitHub': 'github.com',
        'PyPI': 'pypi.org',
        'PyPI清华镜像': 'pypi.tuna.tsinghua.edu.cn',
        'OpenAI API': 'api.openai.com',
        'DeepSeek API': 'api.deepseek.com',
        'Elasticsearch': '119.23.229.39',
        '阿里云OSS': 'oss-cn-shenzhen.aliyuncs.com'
    }
    
    results = {}
    
    for name, host in sites.items():
        try:
            # 提取主机名（去掉协议和路径）
            if '://' in host:
                host = host.split('://')[1].split('/')[0]
            
            # 尝试连接
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(5)
            
            if name == 'Elasticsearch':
                result = sock.connect_ex((host, 39200))
            else:
                result = sock.connect_ex((host, 443))
                
            sock.close()
            
            if result == 0:
                print(f"  ✓ {name}: 可访问")
                results[name] = True
            else:
                print(f"  ✗ {name}: 无法访问")
                results[name] = False
                
        except Exception as e:
            print(f"  ✗ {name}: 连接错误 - {str(e)}")
            results[name] = False
    
    return results

def check_python_environment() -> Dict[str, bool]:
    """检测Python环境"""
    print("\n🐍 检测Python环境...")
    
    results = {}
    
    # 检查Python版本
    python_version = sys.version_info
    if python_version >= (3, 8):
        print(f"  ✓ Python版本: {python_version.major}.{python_version.minor}.{python_version.micro} (符合要求)")
        results['python_version'] = True
    else:
        print(f"  ✗ Python版本: {python_version.major}.{python_version.minor}.{python_version.micro} (需要3.8+)")
        results['python_version'] = False
    
    # 检查pip配置
    try:
        result = subprocess.run(['pip', 'config', 'list'], capture_output=True, text=True, timeout=10)
        if 'tuna.tsinghua.edu.cn' in result.stdout or 'mirrors.aliyun.com' in result.stdout:
            print("  ✓ pip镜像源: 已配置国内镜像")
            results['pip_mirror'] = True
        else:
            print("  ⚠️  pip镜像源: 未配置国内镜像 (建议配置)")
            results['pip_mirror'] = False
    except Exception as e:
        print(f"  ✗ pip配置检查失败: {str(e)}")
        results['pip_mirror'] = False
    
    return results

def check_required_packages() -> Dict[str, bool]:
    """检测必需的Python包"""
    print("\n📦 检测必需的Python包...")
    
    required_packages = [
        'fastapi',
        'uvicorn',
        'pandas',
        'requests',
        'elasticsearch',
        'pymongo',
        'redis',
        'pydantic',
        'python-dotenv',
        'matplotlib',
        'pdfkit',
        'markdown'
    ]
    
    results = {}
    
    for package in required_packages:
        try:
            if importlib.util.find_spec(package) is not None:
                print(f"  ✓ {package}: 已安装")
                results[package] = True
            else:
                print(f"  ✗ {package}: 未安装")
                results[package] = False
        except Exception:
            print(f"  ✗ {package}: 检测失败")
            results[package] = False
    
    return results

def check_external_tools() -> Dict[str, bool]:
    """检测外部工具"""
    print("\n🔧 检测外部工具...")
    
    tools = {
        'wkhtmltopdf': ['wkhtmltopdf', '--version'],
        'git': ['git', '--version'],
        'curl': ['curl', '--version']
    }
    
    results = {}
    
    for tool, command in tools.items():
        try:
            result = subprocess.run(command, capture_output=True, text=True, timeout=10)
            if result.returncode == 0:
                version = result.stdout.split('\n')[0]
                print(f"  ✓ {tool}: {version}")
                results[tool] = True
            else:
                print(f"  ✗ {tool}: 未安装或版本异常")
                results[tool] = False
        except Exception as e:
            print(f"  ✗ {tool}: 检测失败 - {str(e)}")
            results[tool] = False
    
    return results

def check_environment_variables() -> Dict[str, bool]:
    """检测环境变量"""
    print("\n🔐 检测环境变量配置...")
    
    env_vars = {
        'AI服务': ['DEEPSEEK_API_KEY', 'OPENAI_API_KEY'],
        'OSS配置': ['OSS_ACCESS_KEY_ID', 'OSS_ACCESS_KEY_SECRET'],
        '代理配置': ['HTTP_PROXY', 'HTTPS_PROXY']
    }
    
    results = {}
    
    for category, vars_list in env_vars.items():
        has_any = False
        for var in vars_list:
            if os.getenv(var):
                has_any = True
                break
        
        if has_any:
            print(f"  ✓ {category}: 已配置")
            results[category] = True
        else:
            print(f"  ⚠️  {category}: 未配置 (运行时可能需要)")
            results[category] = False
    
    return results

def check_services() -> Dict[str, bool]:
    """检测服务连通性"""
    print("\n🔌 检测服务连通性...")
    
    services = {
        'Elasticsearch': ('119.23.229.39', 39200),
        'MongoDB': ('localhost', 27017),
        'Redis': ('localhost', 6379)
    }
    
    results = {}
    
    for service, (host, port) in services.items():
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(3)
            result = sock.connect_ex((host, port))
            sock.close()
            
            if result == 0:
                print(f"  ✓ {service}: 可连接 ({host}:{port})")
                results[service] = True
            else:
                print(f"  ✗ {service}: 无法连接 ({host}:{port})")
                results[service] = False
        except Exception as e:
            print(f"  ✗ {service}: 连接错误 - {str(e)}")
            results[service] = False
    
    return results

def provide_recommendations(results: Dict[str, Dict[str, bool]]):
    """提供优化建议"""
    print("\n💡 优化建议:")
    
    # 网络连通性建议
    network = results.get('network', {})
    if not network.get('PyPI清华镜像', False):
        print("  🔧 配置pip镜像源: pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple")
    
    if not network.get('DeepSeek API', False) and not network.get('OpenAI API', False):
        print("  🔧 AI服务不可达，建议:")
        print("     - 配置网络代理")
        print("     - 获取DeepSeek API密钥 (推荐，国内服务)")
        print("     - 或配置OpenAI代理访问")
    
    # Python环境建议
    python = results.get('python', {})
    if not python.get('pip_mirror', False):
        print("  🔧 建议配置pip国内镜像源以提升下载速度")
    
    # 包安装建议
    packages = results.get('packages', {})
    missing_packages = [pkg for pkg, installed in packages.items() if not installed]
    if missing_packages:
        print(f"  🔧 安装缺失的包: pip install {' '.join(missing_packages)}")
    
    # 工具安装建议
    tools = results.get('tools', {})
    if not tools.get('wkhtmltopdf', False):
        print("  🔧 安装wkhtmltopdf:")
        print("     Ubuntu/Debian: sudo apt-get install wkhtmltopdf")
        print("     CentOS/RHEL: sudo yum install wkhtmltopdf")
        print("     macOS: brew install wkhtmltopdf")
        print("     Windows: 下载安装 https://wkhtmltopdf.org/downloads.html")
    
    # 环境变量建议
    env = results.get('environment', {})
    if not env.get('AI服务', False):
        print("  🔧 配置AI服务环境变量:")
        print("     export DEEPSEEK_API_KEY='your_api_key_here'")
    
    # 服务连接建议
    services = results.get('services', {})
    if not services.get('MongoDB', False):
        print("  🔧 启动MongoDB服务: sudo systemctl start mongod")
    if not services.get('Redis', False):
        print("  🔧 启动Redis服务: sudo systemctl start redis")

def create_env_template():
    """创建.env模板文件"""
    template_content = """# IoT手环系统环境配置文件
# 复制此文件为.env并填入实际配置值

# ===================
# AI服务配置
# ===================
AI_DEFAULT_PROVIDER=deepseek
DEEPSEEK_API_KEY=your_deepseek_api_key_here
DEEPSEEK_BASE_URL=https://api.deepseek.com

# OpenAI配置（需要代理访问）
OPENAI_API_KEY=your_openai_api_key_here
OPENAI_BASE_URL=https://api.openai.com

# ===================
# 网络代理配置
# ===================
# 如果需要代理访问外网服务，请取消注释并配置
# HTTP_PROXY=http://127.0.0.1:7890
# HTTPS_PROXY=https://127.0.0.1:7890

# ===================
# 数据库配置
# ===================
ELASTICSEARCH_HOSTS=http://119.23.229.39:39200
MONGODB_URL=mongodb://localhost:27017/iot_wristband
REDIS_URL=redis://localhost:6379/0

# ===================
# 文件存储配置
# ===================
OSS_ENDPOINT=https://oss-cn-shenzhen.aliyuncs.com
OSS_BUCKET=landiwulian
OSS_ACCESS_KEY_ID=your_oss_access_key_id
OSS_ACCESS_KEY_SECRET=your_oss_access_key_secret
OSS_BASE_URL=https://landiwulian.oss-cn-shenzhen.aliyuncs.com

# ===================
# PDF生成配置
# ===================
# Linux/macOS
WKHTMLTOPDF_PATH=/usr/local/bin/wkhtmltopdf
# Windows (示例)
# WKHTMLTOPDF_PATH=C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe

# ===================
# 应用配置
# ===================
REPORT_BATCH_SIZE=100
REPORT_BASE_TIMESTAMP=1735660800
REPORT_DEFAULT_TIMEZONE=Asia/Shanghai
"""
    
    env_file_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), '.env.example')
    
    try:
        with open(env_file_path, 'w', encoding='utf-8') as f:
            f.write(template_content)
        print(f"\n📝 已创建环境配置模板: {env_file_path}")
        print("   请复制为.env文件并填入实际配置值")
    except Exception as e:
        print(f"\n❌ 创建环境配置模板失败: {str(e)}")

def main():
    """主函数"""
    print("🚀 IoT手环系统环境检测 (中国大陆网络优化版)")
    print("=" * 60)
    
    # 执行所有检测
    results = {}
    results['network'] = check_network_connectivity()
    results['python'] = check_python_environment()
    results['packages'] = check_required_packages()
    results['tools'] = check_external_tools()
    results['environment'] = check_environment_variables()
    results['services'] = check_services()
    
    # 统计结果
    print("\n" + "=" * 60)
    print("📊 检测结果汇总:")
    
    total_checks = 0
    passed_checks = 0
    
    for category, checks in results.items():
        category_total = len(checks)
        category_passed = sum(1 for result in checks.values() if result)
        total_checks += category_total
        passed_checks += category_passed
        
        print(f"  {category.upper()}: {category_passed}/{category_total} 通过")
    
    print(f"\n总体通过率: {passed_checks}/{total_checks} ({passed_checks/total_checks*100:.1f}%)")
    
    # 提供建议
    provide_recommendations(results)
    
    # 创建环境配置模板
    create_env_template()
    
    print("\n" + "=" * 60)
    if passed_checks / total_checks >= 0.7:
        print("✅ 环境检测基本通过，可以开始开发！")
        print("💡 建议根据上述建议进一步优化环境配置")
    else:
        print("⚠️  环境存在较多问题，建议先解决关键问题再开始开发")
        print("🔧 请参考上述建议进行环境配置")
    
    return passed_checks / total_checks >= 0.7

if __name__ == "__main__":
    try:
        success = main()
        sys.exit(0 if success else 1)
    except KeyboardInterrupt:
        print("\n\n❌ 用户中断检测")
        sys.exit(1)
    except Exception as e:
        print(f"\n\n❌ 检测过程中发生错误: {str(e)}")
        sys.exit(1)